package com.wf.day_0612.test2;

import lombok.Data;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author mpk
 * @since 2024/6/12 17:03:35
 */
@Data
public class Account {

//    属性：name balance
//    方法：Account withdraw(double money)取款方法
//
//    取款线程：1.先判断账户余额是否充足 2.若充足则可以取款成功 3.取款后可以返回最新的账户信息
//    需求：2条取款线程并发访问 同一账户  可能会引发线程不安全的问题？
//            1. 线程1在余额充足时取款后，还没有返回最新账户信息时，但线程2仍然可以取款成功
//     2. 返回最新账户信息时，余额显示为负数
//
//    要求：分别使用synchronized同步代码块 和 lock锁来实现

    private String name;

    private double balance;

    private Lock lock = new ReentrantLock();

    Account withdraw(double money) {

        synchronized (Account.class) {
            return getAccount(money);
        }


    }


    Account withdraw1(double money) {


        try {
            lock.lock();
            return getAccount(money);
        } finally {
            lock.unlock();
        }
    }

    private Account getAccount(double money) {
        if (money < 0) {
            throw new RuntimeException("取款金额不能为负数！！");
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        if (this.balance - money >= 0) {
            this.balance -= money;
            System.out.println("取款成功！" + "余额:" + this.balance);
        } else {
            throw new RuntimeException("余额不足！！" + "余额:" + this.balance);
        }
        return this;
    }

}



